

#ifndef _VECTOR
#  define _VECTOR

#  include "config.h"
#  include <stdio.h>

/* These are the data definitions. */

#  ifndef _VECT_DATA_DECS
#    define _VECT_DATA_DECS
typedef struct vm_vector {

  double x;
  double y;
  double z;
  double w;

} vm_vector __attribute__((aligned (16)));

#    define X_AXIS(V) V.x = 1; V.y = 0; V.z = 0; V.w = 0;
#    define Y_AXIS(V) V.x = 0; V.y = 1; V.z = 0; V.w = 0;
#    define Z_AXIS(V) V.x = 0; V.y = 0; V.z = 1; V.w = 0;
#    define W_AXIS(V) V.x = 0; V.y = 0; V.z = 0; V.w = 1;
#    define ZERO(V)   V.x = 0; V.y = 0; V.z = 0; V.w = 0;

extern vm_vector UNIT_X;
extern vm_vector UNIT_Y;
extern vm_vector UNIT_Z;
extern vm_vector UNIT_W;
#  endif

/* And the function definitions. */

#  ifndef _ONLY_FAST_VECT
void       vm_add(vm_vector, vm_vector, vm_vector *);      // Asn
void       vm_sub(vm_vector, vm_vector, vm_vector *);      // Asm
void       vm_scale(vm_vector, double, vm_vector *);       // Asm
double     vm_magnitude(vm_vector);                        // Asm
void       vm_norm(vm_vector, vm_vector *);                // Asm
void       vm_cross(vm_vector, vm_vector, vm_vector *);    // Asm
void       vm_project(vm_vector, vm_vector, vm_vector *);  // Asm
void       vm_dot(vm_vector, vm_vector, double *);         // Asm     
double     vm_angle(vm_vector, vm_vector);
void       vm_vect_inverse(vm_vector, vm_vector *);
vm_vector *vm_gram_schmidt_orth(vm_vector *, int);
#  endif

void       vm_print(vm_vector);
void       vm_println(vm_vector);
void       vm_fprint(FILE *, vm_vector);
void       vm_fprintln(FILE *, vm_vector);
int        vm_read(FILE *, vm_vector *);
int        vm_sread(char *, vm_vector *);

#endif
